ui = {};
require("lSDL");
require("lSDL_ttf");
require("drw");
require("toType");
local tmpSrcRect = SDL_calloc(4*4,1);
local tmpDstRect = SDL_calloc(4*4,1);
local tmpBuf = SDL_calloc(1024,1);
local strbuf = "abcdef";
local textures = {};
local null = dpointer(0);
function ui.isPlatform(self,name)
    if(name=="SDL2")then
        return true;
    end
    return false;
end

SDL_Init(-1);
TTF_Init();
--SDL_GL_SetSwapInterval(1);

local renderer;
local window;

local symbols = {};

function allocName(name)
    local id = symbols[name];
    if(id==nil)then
        id = 0;
    end
    local n = name .. tostring(id);
    while(symbols[n])do
        id = id + 1;
        n = name .. tostring(id);
    end
    symbols[name] = id;
    symbols[n] = id;
    return n;
end

function setWindow(w)
    window = w;
end

function setRenderer(r)
    local ret = renderer;
    renderer = r;
    return ret;
end

function getWindowSize(w)
    local d0 = dpointer(tmpBuf,0);
    local d1 = dpointer(tmpBuf,4);
    SDL_GetWindowSize(w,d0,d1);
    return dr(d0,0,4),dr(d1,0,4);
end

function setRenderTarget(n)
    local target = null;
    local ret = SDL_GetRenderTarget(renderer);
    if(isstring(n))then
        target = textures[n];
    elseif(islightuserdata(n))then
        target = n;
    end
    if(target~=nil)then
        SDL_SetRenderTarget(renderer,target);
    end
    return ret;
end

function renderPresent()
    SDL_RenderPresent(renderer);
end

function createCanvas(name,w,h,flag)
    if(flag==nil)then
        flag = SDL_TEXTUREACCESS_TARGET|SDL_TEXTUREACCESS_STATIC;
    end
    local texture =  SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888,flag,w,h);
    if(textures[name])then
        SDL_DestroyTexture(textures[name]);
    end
    textures[name] = texture;
end

createRenderTarget = createCanvas;
function cleanTextures()
    for k,v in pairs(textures)do
        print("clean textures",k);
        SDL_DestroyTexture(v);
    end
    textures = {};
end

function draw(name,x,y,w,h,dstx,dsty,dstw,dsth)
    local texture = textures[name];
    --print(SDL_GetRenderTarget(renderer),texture,name);
    if(texture)then
        if(dstx==nil)then dstx = x; x = 0; end;
        if(dsty==nil)then dsty = y; y = 0; end;
        if(dstw==nil)then dstw = w; end;
        if(dsth==nil)then dsth = h; end;
        dw(tmpSrcRect,0,4,x);
        dw(tmpSrcRect,4,4,y);
        dw(tmpSrcRect,8,4,w);
        dw(tmpSrcRect,12,4,h);

        dw(tmpDstRect,0,4,dstx);
        dw(tmpDstRect,4,4,dsty);
        dw(tmpDstRect,8,4,dstw);
        dw(tmpDstRect,12,4,dsth);
        SDL_RenderCopy(renderer,texture,tmpSrcRect,tmpDstRect);
    end
end

function qdraw(name,src,dst)
    local texture = textures[name];
    if(texture)then
        SDL_RenderCopy(renderer,texture,src,dst);
    end
end

function getDrawColor()
    local p0 = dpointer(strbuf);
    local p1 = dpointer(strbuf,1);
    local p2 = dpointer(strbuf,2);
    local p3 = dpointer(strbuf,3);
    SDL_GetRenderDrawColor(renderer,p0,p1,p2,p3);
    return strbuf:byte(1),strbuf:byte(2),strbuf:byte(3),strbuf:byte(4);
end

function drawRect(x,y,w,h,color,fill)
    dw(tmpDstRect,0,4,x);
    dw(tmpDstRect,4,4,y);
    dw(tmpDstRect,8,4,w);
    dw(tmpDstRect,12,4,h);
    local r,g,b,a;
    if(color)then
        r,g,b,a = getDrawColor();
        local rr = color&0xff;
        local gg = (color>>8)& 0xff;
        local bb = (color>>0x10)& 0xff;
        local aa = (color>>0x18)& 0xff;
        SDL_SetRenderDrawColor(renderer,rr,gg,bb,aa);
    end
    if(fill)then
        SDL_RenderFillRect(renderer,tmpDstRect);
    else
        SDL_RenderDrawRect(renderer,tmpDstRect);
    end
    if(color)then
        SDL_SetRenderDrawColor(renderer,r,g,b,a);
    end
end

function drawString(str,w,h,color,fontFile,fontSize)
    local font;
    if(fontFile==nil)then
        fontFile = "Small SimSun.ttf";
    end
    if(fontSize==nil)then
        fontSize = 16;
    end
    if(color==nil)then color = 0xff000000;end;
    if(FontTable==nil)then
        FontTable = {};
    end
    if(FontTable[fontFile]==nil)then
        FontTable[fontFile] = {};
    end
    font = FontTable[fontFile][fontSize];
    if(font==nil)then 
        font = TTF_OpenFont(fontFile,fontSize);
        FontTable[fontFile][fontSize] = font;
    end
    surface = TTF_RenderUTF8_Solid(font,str,color);
    texture = SDL_CreateTextureFromSurface(renderer,surface);

    SDL_QueryTexture(texture,null,null,dpointer(tmpSrcRect,8),dpointer(tmpSrcRect,12));
    SDL_QueryTexture(texture,null,null,dpointer(tmpDstRect,8),dpointer(tmpDstRect,12));

    local tw = dr(tmpDstRect,8,4);
    local th = dr(tmpDstRect,12,4);
    local x = (w - tw) >> 1;
    local y = (h - th) >> 1;
    dw(tmpSrcRect,0,4,0);
    dw(tmpSrcRect,4,4,0);
    dw(tmpDstRect,0,4,x);
    dw(tmpDstRect,4,4,y);

    SDL_RenderCopy(renderer,texture,tmpSrcRect,tmpDstRect);
    SDL_FreeSurface(surface);
end

function drawStringPos(str,x,y,color,fontFile,fontSize)
    local font;
    if(fontFile==nil)then
        fontFile = "Small SimSun.ttf";
    end
    if(fontSize==nil)then
        fontSize = 16;
    end
    if(color==nil)then color = 0xff000000;end;
    if(FontTable==nil)then
        FontTable = {};
    end
    if(FontTable[fontFile]==nil)then
        FontTable[fontFile] = {};
    end
    font = FontTable[fontFile][fontSize];
    if(font==nil)then 
        font = TTF_OpenFont(fontFile,fontSize);
        FontTable[fontFile][fontSize] = font;
    end
    surface = TTF_RenderUTF8_Solid(font,str,color);
    texture = SDL_CreateTextureFromSurface(renderer,surface);

    SDL_QueryTexture(texture,null,null,dpointer(tmpSrcRect,8),dpointer(tmpSrcRect,12));
    SDL_QueryTexture(texture,null,null,dpointer(tmpDstRect,8),dpointer(tmpDstRect,12));

    dw(tmpSrcRect,0,4,0);
    dw(tmpSrcRect,4,4,0);
    dw(tmpDstRect,0,4,x);
    dw(tmpDstRect,4,4,y);

    SDL_RenderCopy(renderer,texture,tmpSrcRect,tmpDstRect);
    SDL_FreeSurface(surface);
end

--清理字体
table.insert(application.quitFuncs,function()
    if(FontTable)then
        for k,v in pairs(FontTable)do
            for kk,vv in pairs(v)do
                TTF_CloseFont(vv);
            end
        end
    end
end);
